
import pandas as pd
from docx import Document
from docx.shared import Pt, RGBColor, Cm
from docx.oxml.ns import qn
from docx.enum.text import WD_PARAGRAPH_ALIGNMENT
from docx.oxml import OxmlElement
import docx2pdf
import subprocess
from docx.shared import RGBColor


def get_obj_id_ispass(data_detail_path):
    df_faultobj = pd.read_pickle(data_detail_path)
    df_job_isnotpass=df_faultobj[df_faultobj['job_isPass'] == '1']
    df_faultobj_list= df_job_isnotpass[['faultid', 'faultobj']].values.tolist()

    list_id = []
    for row in df_faultobj_list:
        faultid = row[0]
        faultobj = row[1]
        # faultdesp = row[2]
        # test_desp = row[3]
        st = faultid + "#" + faultobj
        list_id.append(st)
    list_set = set(list_id)
    return list_set
def get_obj_id_isnotpass(data_detail_path):
    df_faultobj = pd.read_pickle(data_detail_path)
    df_job_isnotpass=df_faultobj[df_faultobj['job_isPass'] == '0']
    df_faultobj_list= df_job_isnotpass[['faultid', 'faultobj']].values.tolist()

    list_id = []
    for row in df_faultobj_list:
        faultid = row[0]
        faultobj = row[1]
        # faultdesp = row[2]
        # test_desp = row[3]
        st = faultid + "#" + faultobj
        list_id.append(st)
    list_set = set(list_id)
    return list_set

def add_doc():
    doc = Document()
    #创建一个文档，设置左边距和右边距（左边距为1.8，右边距为1.5）
    for section in doc.sections:
        section.left_margin = Cm(1.8)
        section.right_margin = Cm(1.5)
    #设置默认正文的字体样式为：微软雅黑
    doc.styles['Normal'].font.name = u'微软雅黑'
    #设置 直接访问样式元素的 XML，然后将中文字体设置为"微软雅黑"
    doc.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'微软雅黑')
    #设置标题：参数 '0' 表示标题级别，通常 0 表示顶级标题
    title = doc.add_heading('', 0)
    #指定 文本对齐方式为居中
    title.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER
    # 设置 文本的标题名称，并创建run对象
    run = title.add_run('数据一致性仿真测试评测报告')
    run.font.name = u'微软雅黑'
    run.font.color.rgb = RGBColor(0, 0, 0)
    run._element.rPr.rFonts.set(qn('w:eastAsia'), u'微软雅黑')

    #不设置目录
    # head_content = doc.add_heading('', 1).add_run('目录')

    catalog_p = doc.add_paragraph('')
    return doc,catalog_p

# 设置目录
def add_directory(catalog_p,doc):
    for paragraph in doc.paragraphs:
        paragraph.paragraph_format.line_spacing = 1

        if ('Heading' in paragraph.style.name) and (paragraph.text not in ['目录', '结论']):
            b = paragraph._element.findall('.//' + qn('w:bookmarkStart'))
            print(b)
            if len(b) >= 1:
                bookmark_name = b[0].get(qn('w:name'))
                text = paragraph.text
                level = int(paragraph.style.name[-1])
                # paragraph.paragraph_format.line_spacing_rule = WD_LINE_SPACING.SINGLE
                print(text, bookmark_name)

                toc_paragraph = catalog_p.insert_paragraph_before(style='Normal')

                if level == 2:
                    toc_paragraph.paragraph_format.first_line_indent = Pt(16)
                if level == 3:
                    toc_paragraph.paragraph_format.first_line_indent = Pt(24)

                tabs = OxmlElement('w:tabs')
                tab1 = OxmlElement('w:tab')
                tab1.set(qn('w:val'), "left")
                tab1.set(qn('w:leader'), "dot")
                tab1.set(qn('w:pos'), "8400")
                tabs.append(tab1)
                toc_paragraph._p.pPr.append(tabs)

                hyperlink = OxmlElement('w:hyperlink')
                hyperlink.set(qn('w:anchor'), bookmark_name)
                hyperlink.set(qn('w:history'), '1')

                hr1 = OxmlElement('w:r')
                rPr = OxmlElement('w:rPr')
                rStyle = OxmlElement('w:rStyle')
                rStyle.set(qn('w:val'), "a4")
                rPr.append(rStyle)
                hr1.text = text
                hr1.append(rPr)
                hyperlink.append(hr1)
                #
                toc_paragraph._p.append(hyperlink)




#结论正文
def add_conclusion(doc,df_signal_all):
    # 结论正文
    try:
        head_content = doc.add_heading('', 1).add_run('结论')
        print("=====================")
        df_signal_all['day'] = df_signal_all['day'].astype(str)

        df_signal_all['hour'] = df_signal_all['hour'].astype(str)

        df_signal_all['package_version'] = df_signal_all['package_version'].astype(str)

        df_signal_all['fail_case_cnt'] = df_signal_all['fail_case_cnt'].astype(int)

        df_signal_all['passed_case_cnt'] = df_signal_all['passed_case_cnt'].astype(int)
        print("=====================")
        total_fail = df_signal_all['fail_case_cnt'].sum()
        total_pass = df_signal_all['passed_case_cnt'].sum()
        total=total_pass+total_fail

        print("total: "+str(total))

        p_1 = doc.add_paragraph().add_run('版本号：{}'.format(df_signal_all['package_version'].iloc[0]))
        p_1 = doc.add_paragraph().add_run('最近一次测试时间： {}'.format(df_signal_all['day'].iloc[0]+df_signal_all['hour'].iloc[0]))
        p_1 = doc.add_paragraph().add_run('测试case {}个，通过的case  {}个，未通过的case  {}个'.format(total,total_pass,total_fail))
        p_10 = doc.add_paragraph().add_run('(详细内容见报告正文)')

        for run in [p_1, p_10]:
            run.font.color.rgb = RGBColor(0, 0, 0)
            run.font.name = '微软雅黑'
            r = run._element.rPr.rFonts.set(qn('w:eastAsia'), '微软雅黑')
    except Exception as e:
        print(e)
        p_10 = doc.add_paragraph().add_run('缺少描述数据')
    return  doc

# 标题添加bookmark书签，生成目录时添加超链接至书签位置
def add_title_with_bookmark(doc, text, style, bookmark_id):
    paragraph = doc.add_paragraph(text, style=style)
    paragraph.paragraph_format.line_spacing = 0.3
    style = paragraph.style
    # style.element.rPr.rFonts.set(qn('w:asciiTheme'), u'微软雅黑')
    style.element.rPr.rFonts.set(qn('w:eastAsiaTheme'), u'微软雅黑')
    run = paragraph.add_run()

    tag = run._r
    start = OxmlElement('w:bookmarkStart')
    start.set(qn('w:id'), str(bookmark_id))
    start.set(qn('w:name'), text)
    tag.append(start)

    tr = OxmlElement('w:r')
    tr.text = ''
    tag.append(tr)

    end = OxmlElement('w:bookmarkEnd')
    end.set(qn('w:id'), str(bookmark_id))
    end.set(qn('w:name'), text)
    tag.append(end)
    return paragraph

#页眉页脚设置：
def set_header_footer(doc,savepath):
    header = doc.sections[0].header  # 获取第一个节的页眉
    paragraph = header.paragraphs[0]  # 获取页眉的第一个段落
    paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.RIGHT  # 设置页眉居中对齐
    run = paragraph.add_run()  # 添加页眉内容、
    # run.add_picture('/data/triggerAnalysis/logo.png', height=Cm(1.0))

    run.add_picture(savepath+"logo.png", height=Cm(1.0))

    footer = doc.sections[0].footer  # 获取第一个节的页脚
    paragraph = footer.paragraphs[0]  # 获取页脚的第一个段落
    run = paragraph.add_run('让高品质智能电动汽车触手可及')  # 添加页脚内容
    run.font.bold = False
    run.font.size = Pt(8)
    run.font.color.rgb = RGBColor(0, 0, 0)
    run.font.name = u'微软雅黑'
    r = run._element.rPr.rFonts.set(qn('w:eastAsia'), u'微软雅黑')
    paragraph.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER  # 设置第页脚居中对齐
    return doc

def get_result(df_desc):
    df_as_list = df_desc.values.tolist()
    result_list = [f"{row[0]}: {row[1]}" for row in df_as_list]
    # 打印结果
    combined_string = ""
    for index, item in enumerate(result_list):
        if index==0:
            combined_string += "结论：" + "\n"
            combined_string += "    "+item + "\n"
            combined_string += "\n"
        else:
            if index==len(result_list)-1:
                combined_string += "    "+item
            else:
                combined_string += "    "+item + "\n"
                combined_string +="\n"

    print(combined_string)
    return  combined_string

def save_pdf(doc,doc_name,pdf_name,savepath):
    doc_file = savepath + doc_name

    doc.save(savepath + doc_name)
    # word转pdf
    # windows下将word转换为pdf
    pdf_file = savepath + pdf_name  # 要生成的文件：不存在
    # 先创建不存在的文件
    f1 = open(pdf_file, 'w')
    f1.close()
    # 再转换往PDF中写入内容
    docx2pdf.convert(doc_file, pdf_file)

def doc_to_pdf(docpath,pdfpath):
    print("docx文件转为pdf文件。。。")
    commands="libreoffice --headless --convert-to pdf  "+docpath+" --outdir  "+pdfpath
    result2 = subprocess.run(commands, shell=True, capture_output=True, text=True)
    print(result2)

def save_doc(doc,doc_file):
    doc.save(doc_file)


#不需要加粗：
def add_content_center(cell, con):
    """
    填写固定信息
    向单元格写入内容,字体加粗
    :param cell:
    :param con:
    :return:
    """
    cell.text = con
    cell.paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.LEFT
    cell.vertical_alignment = WD_PARAGRAPH_ALIGNMENT.LEFT

#填写固定内容
def add_content_center_bold(cell, con):
    """
    填写固定信息
    向单元格写入内容,字体加粗
    :param cell:
    :param con:
    :return:
    """
    cell.text = con
    cell.paragraphs[0].alignment = WD_PARAGRAPH_ALIGNMENT.LEFT
    cell.vertical_alignment = WD_PARAGRAPH_ALIGNMENT.LEFT
    cell.paragraphs[0].runs[0].font.bold = True

def get_table_row1(df):
    df_size = len(df)
    result_list = df['combined_list'].values.tolist()
    num=0
    for contents in result_list:
        fnc_list=contents.replace("[","").replace("]","").split(",")
        num+=len(fnc_list)+2
    return num
def get_table_row2(df):
    df_size = len(df)
    result_list = df['combined_list'].values.tolist()
    print("length: "+str(len(result_list)))

    return len(result_list)
def merge_table(document,df):
    table_row=len(df)+1
    print("table_row: "+str(table_row))
    document.styles['Normal'].font.name = "Times New Roman"
    document.styles['Normal'].element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
    table = document.add_table(rows=table_row, cols=4, style="Table Grid")

    hdr_cells0 = table.rows[0].cells
    add_content_center_bold(hdr_cells0[0], "module")
    add_content_center_bold(hdr_cells0[1], "Test_type")
    add_content_center_bold(hdr_cells0[2], "测试总case数")
    add_content_center_bold(hdr_cells0[2], "测试失败case数")

    result_list = df['combined_list'].values.tolist()
    row_flag = 0
    for index, item in enumerate(result_list):
        fnc_list = item.replace("[", "").replace("]", "").split(",")
        row_size=len(fnc_list)
        # print("index: "+str(index))
        # print("row_size: " + str(row_size))

        if index==0:
            print("index: "+str(index))
            print("row_size: " + str(row_size))
            start=2
            end=start+row_size
            table.cell(start, 0).merge(table.cell(end, 0))
            row_flag=end
        else:
            print("index: " + str(index))
            print("row_size: " + str(row_size))
            start=row_flag+2
            end=start+row_size
            table.cell(start, 0).merge(table.cell(end, 0))
            row_flag = end

    return document,table

def get_table(document,df):
    table_row=len(df)+1
    print("table_row: "+str(table_row))
    document.styles['Normal'].font.name = "Times New Roman"
    document.styles['Normal'].element.rPr.rFonts.set(qn('w:eastAsia'), u'宋体')
    table = document.add_table(rows=table_row, cols=4, style="Table Grid")

    hdr_cells0 = table.rows[0].cells
    add_content_center_bold(hdr_cells0[0], "module")
    add_content_center_bold(hdr_cells0[1], "Test_type")
    add_content_center_bold(hdr_cells0[2], "测试总case数")
    add_content_center_bold(hdr_cells0[3], "测试失败case数")

    return document,table

def add_tables(doc,savepath,pt_version):
    detail_path=savepath+"signal_detail_version_"+pt_version+'.pkl'
    df = pd.read_pickle(detail_path)

    #合并单元格：
    doc,table=get_table(doc,df)

    # 获取表格的总行数
    total_rows = len(table.rows)
    print(total_rows)

    result_list = df[['combined_list','module','test_type']].values.tolist()
    row_num=1
    for index,result in enumerate(result_list):
        content=result[0]
        arr=content.replace("[","").replace("]","").split(",")
        # resultarr = [item.strip('"') for item in results.split(":")]
        for results in arr:
            resultarr = [item.strip('"') for item in results.split("#")]
            hdr_cells = table.rows[row_num].cells
            add_content_center(hdr_cells[0], resultarr[0])
            add_content_center(hdr_cells[1], resultarr[1])
            add_content_center(hdr_cells[2], resultarr[2])
            add_content_center(hdr_cells[3], resultarr[3])
            row_num+=1

    return  doc


def add_title_mark(doc,pt_version,df_signal_all,savepath):
    df_signal_all['day'] = df_signal_all['day'].astype(str)
    df_signal_all['package_version'] = df_signal_all['package_version'].astype(str)
    df_signal_all['total_case_cnt'] = df_signal_all['total_case_cnt'].astype(int)
    df_signal_all['fail_case_cnt'] = df_signal_all['fail_case_cnt'].astype(int)
    df_signal_all['passed_case_cnt'] = df_signal_all['passed_case_cnt'].astype(int)

    p_1 = doc.add_paragraph().add_run('版本号：{}                           最近一次测试时间： {}'.format(df_signal_all['package_version'].iloc[0],df_signal_all['day'].iloc[0]))
    p_2 = doc.add_paragraph().add_run('测试结果：')
    p_3 = doc.add_paragraph().add_run('测试总case数： {}， 未通过的case： {}，通过的case：{}'.format(df_signal_all['total_case_cnt'].iloc[0],df_signal_all['fail_case_cnt'].iloc[0],df_signal_all['passed_case_cnt'].iloc[0]))
    p_4 = doc.add_paragraph().add_run('模块测试情况：')
    doc=add_tables(doc,savepath,pt_version)

    return  doc
def get_report(savepath,pt_version):
    # 创建 doc
    doc,catalog_p=add_doc()
    #获取数据：


    #signal_all
    signal_all_path =savepath + 'signal_total_version_' + pt_version+'.pkl'

    df_signal_all= pd.read_pickle(signal_all_path)

    #设置标题：
    doc=add_title_mark(doc,pt_version,df_signal_all,savepath)

    #页眉页脚设置
    doc=set_header_footer(doc,savepath)

    #设置目录：
    add_directory(catalog_p,doc)

    #生成pdf 文件
    report_name = '数据一致性仿真测试评测报告_'  +pt_version
    doc_name = report_name + '.docx'
    pdf_name = report_name + '.pdf'

    doc_file = savepath + doc_name
    save_doc(doc,doc_file)
    doc_to_pdf(doc_file,savepath)
    # save_pdf(doc, doc_name, pdf_name, savepath)




if __name__ == '__main__':
    pt_date = '20231205'
    pt_hour = '19'
    savepath = '../csv/'
    pt_version_path=savepath + 'signal_pt_version_' + pt_date + '_' + pt_hour + '.pkl'
    df_pt_version = pd.read_pickle(pt_version_path)
    df_pt_version['pt_version'] = df_pt_version['pt_version'].astype(str)
    pt_version = str(df_pt_version['pt_version'].iloc[0])
    print(pt_version)
    get_report(savepath,pt_version)
